<template>
  <el-collapse v-model="expandAll">
    <el-collapse-item
      v-if="basicChangeMap && basicChangeMap.size > 0"
      :title="t('ustcstudent.view.tab.basic')"
      name="1"
    >
      <el-descriptions :column="3" border label-width="80">
        <template v-for="([key, value], index) in basicChangeMapEntries" :key="index">
          <el-descriptions-item :label="t('ustcstudent.view.modifyField')" width="220">
            {{ key }}
          </el-descriptions-item>
          <el-descriptions-item :label="t('ustcstudent.view.modifyBefore')" width="220">
            {{ value.oldValue }}
          </el-descriptions-item>
          <el-descriptions-item :label="t('ustcstudent.view.modifyAfter')" width="220">
            {{ value.newValue }}
          </el-descriptions-item>
        </template>
      </el-descriptions>
    </el-collapse-item>

    <el-collapse-item
      v-if="universityChangeMap && universityChangeMap.size > 0"
      :title="t('ustcstudent.view.tab.university')"
      name="2"
    >
      <el-descriptions :column="3" border label-width="80">
        <template v-for="([key, value], index) in universityChangeMapEntries" :key="index">
          <el-descriptions-item :label="t('ustcstudent.view.modifyField')" width="220">
            {{ key }}
          </el-descriptions-item>
          <el-descriptions-item :label="t('ustcstudent.view.modifyBefore')" width="220">
            {{ value.oldValue }}
          </el-descriptions-item>
          <el-descriptions-item :label="t('ustcstudent.view.modifyAfter')" width="220">
            {{ value.newValue }}
          </el-descriptions-item>
        </template>
      </el-descriptions>
    </el-collapse-item>
    <el-collapse-item
      v-if="admissionChangeMap && admissionChangeMap.size > 0"
      :title="t('ustcstudent.view.tab.admission')"
      name="3"
    >
      <el-descriptions :column="3" border label-width="80">
        <template v-for="([key, value], index) in admissionChangeMapEntries" :key="index">
          <el-descriptions-item :label="t('ustcstudent.view.modifyField')" width="220">
            {{ key }}
          </el-descriptions-item>
          <el-descriptions-item :label="t('ustcstudent.view.modifyBefore')" width="220">
            {{ value.oldValue }}
          </el-descriptions-item>
          <el-descriptions-item :label="t('ustcstudent.view.modifyAfter')" width="220">
            {{ value.newValue }}
          </el-descriptions-item>
        </template>
      </el-descriptions>
    </el-collapse-item>
    <el-collapse-item
      v-if="degreeChangeMap && degreeChangeMap.size > 0"
      :title="t('ustcstudent.view.tab.degree')"
      name="4"
    >
      <el-descriptions :column="3" border label-width="80">
        <template v-for="([key, value], index) in degreeChangeMapEntries" :key="index">
          <el-descriptions-item :label="t('ustcstudent.view.modifyField')" width="220">
            {{ key }}
          </el-descriptions-item>
          <el-descriptions-item :label="t('ustcstudent.view.modifyBefore')" width="220">
            {{ value.oldValue }}
          </el-descriptions-item>
          <el-descriptions-item :label="t('ustcstudent.view.modifyAfter')" width="220">
            {{ value.newValue }}
          </el-descriptions-item>
        </template>
      </el-descriptions>
    </el-collapse-item>
    <el-collapse-item
      v-if="personalChangeMap && personalChangeMap.size > 0"
      :title="t('ustcstudent.view.tab.personal')"
      name="5"
    >
      <el-descriptions :column="3" border label-width="80">
        <template v-for="([key, value], index) in personalChangeMapEntries" :key="index">
          <el-descriptions-item :label="t('ustcstudent.view.modifyField')" width="220">
            {{ key }}
          </el-descriptions-item>
          <el-descriptions-item :label="t('ustcstudent.view.modifyBefore')" width="220">
            {{ value.oldValue }}
          </el-descriptions-item>
          <el-descriptions-item :label="t('ustcstudent.view.modifyAfter')" width="220">
            {{ value.newValue }}
          </el-descriptions-item>
        </template>
      </el-descriptions>
    </el-collapse-item>
    <el-collapse-item
      v-if="workChangeMap && workChangeMap.size > 0"
      :title="t('ustcstudent.view.tab.work')"
      name="6"
    >
      <el-descriptions :column="3" border label-width="80">
        <template v-for="([key, value], index) in workChangeMapEntries" :key="index">
          <el-descriptions-item :label="t('ustcstudent.view.modifyField')" width="220">
            {{ key }}
          </el-descriptions-item>
          <el-descriptions-item :label="t('ustcstudent.view.modifyBefore')" width="220">
            {{ value.oldValue }}
          </el-descriptions-item>
          <el-descriptions-item :label="t('ustcstudent.view.modifyAfter')" width="220">
            {{ value.newValue }}
          </el-descriptions-item>
        </template>
      </el-descriptions>
    </el-collapse-item>
  </el-collapse>
</template>

<script setup lang="ts">
import { UstcStudentInfoView } from '@/types/ustcstudent'
import { compareAndFilter } from '@/utils'
import { useI18n } from 'vue-i18n'
import { formatDate } from '@/utils/formatTime'

const props = defineProps<{
  studentInfo: UstcStudentInfoView
  studentInfoBackup: UstcStudentInfoView
}>()

const { t } = useI18n()

interface ChangedValue {
  oldValue: string
  newValue: string
}

const basicChangeMap = ref<Map<string, ChangedValue>>()
const universityChangeMap = ref<Map<string, ChangedValue>>()
const admissionChangeMap = ref<Map<string, ChangedValue>>()
const degreeChangeMap = ref<Map<string, ChangedValue>>()
const personalChangeMap = ref<Map<string, ChangedValue>>()
const workChangeMap = ref<Map<string, ChangedValue>>()

const basicChangeMapEntries = computed(() =>
  Array.from((basicChangeMap.value ?? new Map()).entries())
)
const universityChangeMapEntries = computed(() =>
  Array.from((universityChangeMap.value ?? new Map()).entries())
)
const admissionChangeMapEntries = computed(() =>
  Array.from((admissionChangeMap.value ?? new Map()).entries())
)
const degreeChangeMapEntries = computed(() =>
  Array.from((degreeChangeMap.value ?? new Map()).entries())
)
const personalChangeMapEntries = computed(() =>
  Array.from((personalChangeMap.value ?? new Map()).entries())
)
const workChangeMapEntries = computed(() =>
  Array.from((workChangeMap.value ?? new Map()).entries())
)

const expandAll = ref(['1', '2', '3', '4', '5', '6'])
const basicDate = ['birthdate']
const universityDate = [
  'admissionTime',
  'basicPeriod',
  'longestPeriod',
  'fundingPeriod',
  'defenseDate',
  'leaveDate',
  'graduationDate',
  'degreeDate'
]
const admissionDate = []
const degreeDate = [
  'undergraduateDate',
  'bachelorDate',
  'masterGraduateDate',
  'masterQualificationDate'
]
const personalDate = []
const workDate = ['startDate', 'endDate']

const init = () => {
  // 记录改动的Map
  basicChangeMap.value = new Map<string, ChangedValue>()
  universityChangeMap.value = new Map<string, ChangedValue>()
  admissionChangeMap.value = new Map<string, ChangedValue>()
  degreeChangeMap.value = new Map<string, ChangedValue>()
  personalChangeMap.value = new Map<string, ChangedValue>()
  workChangeMap.value = new Map<string, ChangedValue>()

  // 计算出新值有哪些
  const newValue = compareAndFilter(props.studentInfo, props.studentInfoBackup)
  // 计算出旧值有哪些
  const oldValue = compareAndFilter(props.studentInfoBackup, props.studentInfo)

  // 遍历新值
  for (const key in newValue) {
    // 如果是基本信息
    if (key === 'basic') {
      // 基本信息是扁平的 没有对象属性
      const student = newValue[key]
      for (const subKey in student) {
        basicChangeMap.value.set(t(`ustcstudent.fields.${subKey}`), {
          oldValue: basicDate.includes(subKey)
            ? formatDate(oldValue[key]?.[subKey], 'YYYY-MM-DD')
            : oldValue[key]?.[subKey],
          newValue: basicDate.includes(subKey)
            ? formatDate(student?.[subKey], 'YYYY-MM-DD')
            : student?.[subKey]
        })
      }
    }
    // 如果是在校信息
    if (key === 'university') {
      // 在校信息是扁平的 没有对象属性
      const university = newValue[key]
      for (const subKey in university) {
        universityChangeMap.value.set(t(`ustcStudentInfoUniversity.fields.${subKey}`), {
          oldValue: universityDate.includes(subKey)
            ? formatDate(oldValue[key]?.[subKey], 'YYYY-MM-DD')
            : oldValue[key]?.[subKey],
          newValue: universityDate.includes(subKey)
            ? formatDate(university?.[subKey], 'YYYY-MM-DD')
            : university?.[subKey]
        })
      }
    }
    // 如果是入学信息
    if (key === 'admission') {
      // 入学信息是扁平的 没有对象属性
      const admission = newValue[key]
      for (const subKey in admission) {
        admissionChangeMap.value.set(t(`ustcStudentInfoAdmission.fields.${subKey}`), {
          oldValue: admissionDate.includes(subKey)
            ? formatDate(oldValue[key]?.[subKey], 'YYYY-MM-DD')
            : oldValue[key]?.[subKey],
          newValue: admissionDate.includes(subKey)
            ? formatDate(admission?.[subKey], 'YYYY-MM-DD')
            : admission?.[subKey]
        })
      }
    }
    // 如果是本科/硕士信息
    if (key === 'degree') {
      // 本科/硕士信息是对象属性
      const degree = newValue[key]
      for (const subKey in degree) {
        degreeChangeMap.value.set(t(`ustcStudentInfoDegree.fields.${subKey}`), {
          oldValue: degreeDate.includes(subKey)
            ? formatDate(oldValue[key]?.[subKey], 'YYYY-MM-DD')
            : oldValue[key]?.[subKey],
          newValue: degreeDate.includes(subKey)
            ? formatDate(degree?.[subKey], 'YYYY-MM-DD')
            : degree?.[subKey]
        })
      }
    }
    // 如果是个人联系信息
    if (key === 'personal') {
      // 个人联系信息中有一个对象属性 familyCrew
      const personal = newValue[key]
      for (const personalKey in personal) {
        if (personalKey === 'familyCrew') {
          // 继续迭代 familyCrew 中的属性
          const familyCrew = personal?.[personalKey]
          for (const rowIndex in familyCrew) {
            const familyCrewRow = familyCrew?.[rowIndex]
            for (const familyCrewRowKey in familyCrewRow) {
              const lineNumber = Number(rowIndex) + 1
              const mapKey =
                t('ustcstudent.view.tabPersonal.family') +
                ' ' +
                t('ustcstudent.view.lineNumber', { line: lineNumber }) +
                t(`ustcStudentInfoFamily.fields.${familyCrewRowKey}`)
              personalChangeMap.value.set(mapKey, {
                oldValue: personalDate.includes(familyCrewRowKey)
                  ? formatDate(
                      oldValue[key]?.[personalKey][rowIndex][familyCrewRowKey],
                      'YYYY-MM-DD'
                    )
                  : oldValue[key]?.[personalKey][rowIndex][familyCrewRowKey],
                newValue: personalDate.includes(familyCrewRowKey)
                  ? formatDate(familyCrewRow?.[familyCrewRowKey], 'YYYY-MM-DD')
                  : familyCrewRow?.[familyCrewRowKey]
              })
            }
          }
        } else {
          // 扁平部分的属性 直接处理
          personalChangeMap.value.set(t(`ustcStudentInfoPersonal.fields.${personalKey}`), {
            oldValue: personalDate.includes(personalKey)
              ? formatDate(oldValue[key]?.[personalKey], 'YYYY-MM-DD')
              : oldValue[key]?.[personalKey],
            newValue: personalDate.includes(personalKey)
              ? formatDate(personal?.[personalKey], 'YYYY-MM-DD')
              : personal?.[personalKey]
          })
        }
      }
    }
    // 如果是工作教育经历
    if (key === 'work') {
      // 工作教育经历中有两个对象属性 works 和 educations
      const work = newValue[key]
      for (const workKey in work) {
        if (workKey === 'works') {
          // 继续迭代 works 中的属性
          const works = work?.[workKey]
          for (const rowIndex in works) {
            const workRow = works?.[rowIndex]
            for (const workRowKey in workRow) {
              const lineNumber = Number(rowIndex) + 1
              const mapKey =
                t('ustcstudent.view.tabExp.work') +
                ' ' +
                t('ustcstudent.view.lineNumber', { line: lineNumber }) +
                t(`ustcStudentInfoWorkExp.fields.${workRowKey}`)
              workChangeMap.value.set(mapKey, {
                oldValue: workDate.includes(workRowKey)
                  ? formatDate(oldValue[key]?.[workKey][rowIndex][workRowKey], 'YYYY-MM-DD')
                  : oldValue[key]?.[workKey][rowIndex][workRowKey],
                newValue: workDate.includes(workRowKey)
                  ? formatDate(workRow?.[workRowKey], 'YYYY-MM-DD')
                  : workRow?.[workRowKey]
              })
            }
          }
        } else if (workKey === 'educations') {
          // 继续迭代 educations 中的属性
          const educations = work?.[workKey]
          for (const rowIndex in educations) {
            const educationRow = educations?.[rowIndex]
            for (const educationRowKey in educationRow) {
              const lineNumber = Number(rowIndex) + 1
              const mapKey =
                t('ustcstudent.view.tabExp.education') +
                ' ' +
                t('ustcstudent.view.lineNumber', { line: lineNumber }) +
                t(`ustcStudentInfoStudyExp.fields.${educationRowKey}`)
              workChangeMap.value.set(mapKey, {
                oldValue: workDate.includes(educationRowKey)
                  ? formatDate(oldValue[key]?.[workKey][rowIndex][educationRowKey], 'YYYY-MM-DD')
                  : oldValue[key]?.[workKey][rowIndex][educationRowKey],
                newValue: workDate.includes(educationRowKey)
                  ? formatDate(educationRow?.[educationRowKey], 'YYYY-MM-DD')
                  : educationRow?.[educationRowKey]
              })
            }
          }
        }
      }
    }
  }
}

const getModifyField = (): string => {
  return [
    ...Array.from(basicChangeMap.value?.keys() ?? []),
    ...Array.from(universityChangeMap.value?.keys() ?? []),
    ...Array.from(admissionChangeMap.value?.keys() ?? []),
    ...Array.from(degreeChangeMap.value?.keys() ?? []),
    ...Array.from(personalChangeMap.value?.keys() ?? []),
    ...Array.from(workChangeMap.value?.keys() ?? [])
  ].join('、')
}

onMounted(() => {
  init()
})

defineExpose({ getModifyField })
</script>
